package com.expert.miniapp.service.impl;

import com.expert.miniapp.dao.Case;
import com.expert.miniapp.dao.CaseMapper;
import com.expert.miniapp.dao.RecommendationItemMapper;
import com.expert.miniapp.dto.CaseDTO;
import com.expert.miniapp.dto.RecommendationItemDetailDTO;
import com.expert.miniapp.service.CaseService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * CaseServiceImpl - 案例服务实现类
 *
 * @author System
 * @since 2025-10-19
 */
@Service
public class CaseServiceImpl implements CaseService {

    private static final Logger logger = LoggerFactory.getLogger(CaseServiceImpl.class);

    @Autowired
    private CaseMapper caseMapper;

    @Autowired
    private RecommendationItemMapper recommendationItemMapper;

    /**
     * 分页查询案例列表
     *
     * @param pageNum  页码
     * @param pageSize 每页记录数
     * @return 分页信息
     */
    @Override
    public PageInfo<CaseDTO> getCaseList(int pageNum, int pageSize) {
        logger.info("查询案例列表: pageNum={}, pageSize={}", pageNum, pageSize);

        try {
            // 使用PageHelper进行分页
            PageHelper.startPage(pageNum, pageSize);

            // 查询案例列表（包含关联的用户和资源信息）
            List<CaseDTO> cases = caseMapper.findAllCasesWithDetails();

            // 封装分页信息
            PageInfo<CaseDTO> pageInfo = new PageInfo<>(cases);

            logger.info("查询成功，共查询到 {} 条案例记录，当前页 {} 条", pageInfo.getTotal(), pageInfo.getList().size());

            return pageInfo;
        } catch (Exception e) {
            logger.error("查询案例列表失败", e);
            throw new RuntimeException("查询案例列表失败：" + e.getMessage(), e);
        }
    }

    /**
     * 根据ID查询案例详情
     *
     * @param caseId 案例ID
     * @return 案例详情
     */
    @Override
    public CaseDTO getCaseDetail(String caseId) {
        logger.info("查询案例详情: caseId={}", caseId);

        try {
            // 查询案例详情（包含关联的用户和资源信息）
            CaseDTO caseDTO = caseMapper.findCaseDetailById(caseId);

            if (caseDTO == null) {
                logger.warn("案例不存在: caseId={}", caseId);
            } else {
                logger.info("查询案例详情成功: caseId={}", caseId);
            }

            return caseDTO;
        } catch (Exception e) {
            logger.error("查询案例详情失败: caseId={}", caseId, e);
            throw new RuntimeException("查询案例详情失败：" + e.getMessage(), e);
        }
    }

    /**
     * 从推荐项添加案例
     *
     * @param itemId 推荐项ID
     * @return 新创建的案例详情DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CaseDTO addCaseFromRecommendation(String itemId) {
        logger.info("开始添加案例: itemId={}", itemId);

        // 1. 验证参数
        if (itemId == null || itemId.trim().isEmpty()) {
            logger.warn("推荐项ID不能为空");
            throw new IllegalArgumentException("推荐项ID不能为空");
        }

        try {
            // 2. 检查是否已存在
            Case existingCase = caseMapper.findByItemId(itemId);
            if (existingCase != null) {
                logger.warn("该推荐项已在案例库中: itemId={}, caseId={}", itemId, existingCase.getCaseId());
                throw new RuntimeException("该推荐项已在案例库中");
            }

            // 3. 查询推荐项详情（包含用户和需求信息）
            RecommendationItemDetailDTO itemDetail = recommendationItemMapper.findDetailByItemId(itemId);
            if (itemDetail == null) {
                logger.warn("推荐项不存在: itemId={}", itemId);
                throw new RuntimeException("推荐项不存在");
            }

            logger.info("推荐项详情: userId={}, demandId={}, resourceType={}, resourceId={}",
                    itemDetail.getUser().getUserId(), itemDetail.getDemand().getDemandId(),
                    itemDetail.getResourceType(), itemDetail.getResourceId());

            // 4. 获取最大num并递增
            Integer maxNum = caseMapper.getMaxNum();
            int nextNum = (maxNum == null) ? 1 : maxNum + 1;
            logger.info("当前最大num={}, 新案例num={}", maxNum, nextNum);

            // 5. 创建案例对象
            Case caseEntity = new Case();
            caseEntity.setCaseId(UUID.randomUUID().toString());
            caseEntity.setItemId(itemId);
            caseEntity.setUserId(itemDetail.getUser().getUserId());
            caseEntity.setDemandId(itemDetail.getDemand().getDemandId());
            caseEntity.setResourceType(itemDetail.getResourceType());
            caseEntity.setResourceId(itemDetail.getResourceId());
            caseEntity.setNum(nextNum);
            caseEntity.setCreatedAt(LocalDateTime.now());

            // 6. 插入案例记录
            int rows = caseMapper.insert(caseEntity);
            if (rows == 0) {
                logger.error("插入案例记录失败");
                throw new RuntimeException("添加案例失败");
            }

            logger.info("案例记录插入成功: caseId={}, num={}", caseEntity.getCaseId(), nextNum);

            // 7. 更新推荐项的is_added_to_case标记
            int updateRows = recommendationItemMapper.updateIsAddedToCase(itemId, true);
            if (updateRows == 0) {
                logger.error("更新is_added_to_case标记失败");
                throw new RuntimeException("更新推荐项状态失败");
            }

            logger.info("推荐项is_added_to_case标记更新成功: itemId={}", itemId);

            // 8. 查询并返回完整的案例详情
            CaseDTO caseDTO = caseMapper.findCaseDetailById(caseEntity.getCaseId());
            if (caseDTO == null) {
                logger.error("查询新创建的案例详情失败: caseId={}", caseEntity.getCaseId());
                throw new RuntimeException("查询案例详情失败");
            }

            logger.info("案例添加成功: caseId={}, num={}, userId={}, demandId={}",
                    caseDTO.getCaseId(), caseDTO.getNum(), caseDTO.getUserId(), caseDTO.getDemandId());

            return caseDTO;

        } catch (IllegalArgumentException e) {
            // 参数异常，重新抛出
            throw e;
        } catch (RuntimeException e) {
            // 业务异常（包括推荐项不存在、已存在等），重新抛出
            throw e;
        } catch (Exception e) {
            logger.error("添加案例失败: itemId={}", itemId, e);
            throw new RuntimeException("添加案例失败：" + e.getMessage(), e);
        }
    }
}
